home *** CD-ROM | disk | FTP | other *** search
/ Extra! Mainframe / Extra! Mainframe for Windows 95.iso / snaserv / source / parseca.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-01  |  12.1 KB  |  564 lines

  1. /***************************************************************************
  2. **
  3. **    File:            PARSECA.C
  4. **    Purpose:        Custom Action data parsing routines
  5. **                    for the Sample App DLL.
  6. **    Notes:
  7. **
  8. ****************************************************************************/
  9.  
  10. #define PARSECA_C
  11.  
  12. #include "stdinc.h"
  13. #include <stdlib.h>        /* _MAX_PATH */
  14. #include <ctype.h>        /* isdigit */
  15. #include "setupapi.h"
  16. #include "cui.h"
  17. #include "stdtypes.h"
  18. #include "setupkit.h"
  19. #include "datadef.h"
  20. #include "parseca.h"
  21. #include "snaccacb.h"
  22.  
  23.  
  24. /* REVIEW: Put the strings in sampsz.h.
  25. */
  26. #define STR_BADSECT_ERR  "InstallWinPermFile Object: Bad INF Section data value"
  27. #define STR_BADKEY_ERR   "InstallWinPermFile Object: Bad INF Key data value"
  28. #define STR_XTRADATA_ERR "InstallWinPermFile Object: extra unrecognized data values"
  29. #define STR_PARSE_ERR    "Setup Parse Error in Initialize pass"
  30. #define STR_OBJID        "Object ID %d: %s."
  31. #define STR_MISSING_ERR  "SingSelListDlg Object: Missing data value"
  32. #define STR_BADDATA_ERR  "SingSelListDlg Object: Bad data value"
  33. #define STR_OBJID_ERR    "Syntax Error in List of Obj IDs"
  34.  
  35.  
  36. const CHAR chFieldSep = chTab;
  37. #define FWhiteSpaceCh(ch)    ((BOOL)((ch) == chSpace || (ch) == chTab))
  38. #define chLorSep    chComma
  39.  
  40.  
  41. /*
  42. ****************************************************************************/
  43. RC PUBLIC RcParseInfSectKey ( OR orCur, SZ szData, PSZ pszInfSect,
  44.                     PSZ pszInfKey )
  45. {
  46.     Assert(szData     != szNull);
  47.     Assert(pszInfSect != pszNull);
  48.     Assert(pszInfKey  != pszNull);
  49.  
  50.     if (*pszInfSect != szNull)    /* Already parsed and alloc'ed? */
  51.         return (rcOk);
  52.  
  53.     if (!FReadDataFieldString(&szData, pszInfSect))
  54.         return (rcFail);
  55.     Assert(*pszInfSect != szNull);
  56.     if (!FValidInfSection(*pszInfSect) || !DoesInfSectionExist(*pszInfSect))
  57.         {
  58.         ParseError(orCur, STR_BADSECT_ERR);
  59.         return (rcFail);
  60.         }
  61.  
  62.     if (!FReadDataFieldString(&szData, pszInfKey))
  63.         return (rcFail);
  64.     Assert(*pszInfKey != szNull);
  65.     if (!FValidInfKey(*pszInfKey)
  66.             || !DoesInfSectionKeyExist(*pszInfSect, *pszInfKey))
  67.         {
  68.         ParseError(orCur, STR_BADKEY_ERR);
  69.         return (rcFail);
  70.         }
  71.  
  72.     if (*szData != chEos)
  73.         {
  74.         ParseError(orCur, STR_XTRADATA_ERR);
  75.         return (rcFail);
  76.         }
  77.  
  78.     return (rcOk);
  79. }
  80.  
  81.  
  82. /*
  83. ************************************************************************/
  84. RC PUBLIC RcParseLor ( PCD pcd, OR orCur, SZ szData, PPLOR pplor )
  85. {
  86.     Assert(pcd != lpvoidNull);
  87.     Assert(FValidOr(pcd, orCur));
  88.     Assert(szData != szNull);
  89.     Assert(pplor  != pplorNull);
  90.  
  91.     if (*pplor != plorNull)
  92.         return (rcOk);
  93.  
  94.     while (FWhiteSpaceCh(*szData))
  95.         szData = SzNextChar(szData);
  96.  
  97.     if (*szData == chEos)
  98.         {
  99.         ParseError(orCur, STR_MISSING_ERR);
  100.         return (rcFail);
  101.         }
  102.  
  103.     /* OOM or non-digit chars msg handled inside PlorFromSz()
  104.     */
  105.     if ((*pplor = PlorFromSz(orCur, szData)) == plorNull)
  106.         return (rcFail);
  107.  
  108.     if (!FValidGroupPlor(pcd, *pplor, orCur))
  109.         {
  110.         FFreePlor(pplor);
  111.         ParseError(orCur, STR_BADDATA_ERR);
  112.         return (rcFail);
  113.         }
  114.  
  115.     return (rcOk);
  116. }
  117.  
  118.  
  119. /*
  120. ************************************************************************/
  121. BOOL PUBLIC FReadDataFieldString ( PSZ pszData, PSZ pszMember )
  122. {
  123.     CHAR rgch[cchSzMax];
  124.  
  125.     Assert(pszData != pszNull);
  126.     Assert(*pszData != szNull);
  127.     Assert(pszMember != pszNull);
  128.  
  129.     *pszData = SzGetTableField(*pszData, rgch, cchSzMax, chComma);
  130.  
  131.     if (*pszData == szNull)
  132.         return (fFalse);
  133.  
  134.     if ((*pszMember = SzStrDupl(rgch)) == szNull)
  135.         return (fFalse);
  136.  
  137.     return (fTrue);
  138. }
  139.  
  140.  
  141. /*
  142. **    Purpose:
  143. **        Duplicates a string.
  144. **    Arguments:
  145. **        sz: string to duplicate.
  146. **    Returns:
  147. **        duplicated string if successful, szNull if not.
  148. **    Notes:
  149. ****************************************************************************/
  150. SZ PUBLIC SzStrDupl ( SZ sz )
  151. {
  152.     SZ szNew;
  153.  
  154.     Assert(sz != szNull);
  155.  
  156.     while ((szNew = (SZ)PbAlloc(CbStrLen(sz) + 1)) == szNull)
  157.         {
  158.         if (!FHandleOOM())
  159.             return (szNull);
  160.         }
  161.     SzStrCopy(szNew, sz);
  162.     return (szNew);
  163. }
  164.  
  165.  
  166. /*
  167. **    Purpose:
  168. **        Determine if a string is a valid Inf section.
  169. **    Arguments:
  170. **        szSection: The section.
  171. **    Returns:
  172. **        fTrue if the string is valid, fFalse otherwise.
  173. **    Notes:
  174. **
  175. ****************************************************************************/
  176. BOOL PUBLIC FValidInfSection ( SZ szSection )
  177. {
  178.     SZ szLast;
  179.  
  180.     if (FEmptySz(szSection))
  181.         return (fFalse);
  182.  
  183.     if (*szSection == chSpace)
  184.         return (fFalse);
  185.  
  186.     szLast = szSection;
  187.     while (*szSection != chEos)
  188.         {
  189.         if (*szSection == chRgtSqBracket)
  190.             return (fFalse);
  191.         szLast = szSection;
  192.         szSection = SzNextChar(szSection);
  193.         }
  194.  
  195.     if (*szLast == chSpace)
  196.         return (fFalse);
  197.  
  198.     return (fTrue);
  199. }
  200.  
  201.  
  202. /*
  203. **    Purpose:
  204. **        Determine if a string is a valid Inf key.
  205. **    Arguments:
  206. **        szKey: The key.
  207. **    Returns:
  208. **        fTrue if the string is valid, fFalse otherwise.
  209. **    Notes:
  210. **
  211. ****************************************************************************/
  212. BOOL PUBLIC FValidInfKey ( SZ szKey )
  213. {
  214.     SZ szLast;
  215.  
  216.     if (FEmptySz(szKey))
  217.         return (fFalse);
  218.  
  219.     if (*szKey == chSpace || *szKey == chLftSqBracket)
  220.         return (fFalse);
  221.  
  222.     szLast = szKey;
  223.     while (*szKey != chEos)
  224.         {
  225.         if (*szKey == chEquals)
  226.             return (fFalse);
  227.         szLast = szKey;
  228.         szKey = SzNextChar(szKey);
  229.         }
  230.  
  231.     if (*szLast == chSpace)
  232.         return (fFalse);
  233.  
  234.     return (fTrue);
  235. }
  236.  
  237.  
  238. /*
  239. **    Notes
  240. **        Each OR in the PLOR must be greater than the group OR (which
  241. **        implicitly is greater than orNil).  This prevents circular
  242. **        references and makes processing easier since it can run top
  243. **        to bottom.
  244. ************************************************************************/
  245. BOOL PUBLIC FValidGroupPlor ( PCD pcd, PLOR plor, OR orGroup )
  246. {
  247.     UINT ior;
  248.  
  249.     Assert(plor != plorNull);
  250.     Assert(plor->cor > 0);
  251.     Assert(plor->rgor != rgorNull);
  252.     Assert(orGroup != orNil);
  253.  
  254.     for (ior = 0; ior < plor->cor; ior++)
  255.         {
  256.         OR   or = plor->rgor[ior];
  257.         UINT iorT;
  258.  
  259.         if (or <= orGroup
  260.                 || or >= pcd->cObjectsMax
  261.                 || PodGetObjData(pcd, or) == podNull)
  262.             {
  263.             return (fFalse);
  264.             }
  265.  
  266.  
  267.         for (iorT = ior + 1; iorT < plor->cor; iorT++)
  268.             {
  269.             if (or == plor->rgor[iorT])
  270.                 return (fFalse);
  271.             }
  272.         }
  273.  
  274.     return (fTrue);
  275. }
  276.  
  277.  
  278. /*
  279. **    Purpose:
  280. **        Show a Message Box with the appropriate info.
  281. **    Arguments:
  282. **        or:     object reference number.
  283. **        szcMsg: The error message.
  284. **    Returns:
  285. **        none.
  286. **    Notes:
  287. **
  288. ****************************************************************************/
  289. VOID PUBLIC ParseError ( OR or, SZ szMsg )
  290. {
  291.     CHAR rgchText[2*cchSzMax];
  292.  
  293.     Assert(CbStrLen(STR_OBJID) + 5 + CbStrLen(szMsg) < sizeof rgchText);
  294.     wsprintf(rgchText, STR_OBJID, or, szMsg);
  295.     DoMsgBox(rgchText, STR_PARSE_ERR, MB_OK | MB_ICONEXCLAMATION);
  296. }
  297.  
  298.  
  299. /*
  300. **    Purpose:
  301. **        Extract the first field in szLine.
  302. **    Arguments:
  303. **        szLine:     The buffer to parse for a field.
  304. **        szField:    The buffer to receive the field.
  305. **        cbFieldMax: The size of the output buffer.
  306. **        chSep:        The separator character.
  307. **    Returns:
  308. **        A pointer to the start of the next field in szLine.
  309. **        szNull if an error was detected.
  310. **    Notes:
  311. **
  312. ****************************************************************************/
  313. SZ PUBLIC SzGetTableField ( SZ szLine, SZ szField, CB cbFieldMax,
  314.                             CHAR chSep )
  315. {
  316.     BOOL fQuotedField   = fFalse;
  317.     BOOL fInQuotedField = fFalse;
  318.     CB   cbFieldMaxCur  = cbFieldMax;
  319.     SZ   szFieldEnd     = szField;
  320. #ifdef DEBUG
  321.     SZ   szLineStart    = szLine;
  322.     SZ   szFieldStart   = szField;
  323. #endif
  324.  
  325.     Assert(szLine  != szNull);
  326.     Assert(szField != szNull);
  327.     Assert(cbFieldMax > 0);
  328.  
  329.     *szField = chEos;
  330.     cbFieldMaxCur--;
  331.  
  332.     Assert(chSep != chSpace);
  333.     while (FWhiteSpaceCh(*szLine) && *szLine != chSep)
  334.         szLine = SzNextChar(szLine);
  335.  
  336.     if (*szLine == chDblQuote)    /* Strip off the outermost set of quotes. */
  337.         {
  338.         fQuotedField   = fTrue;
  339.         fInQuotedField = fTrue;
  340.         szLine = SzNextChar(szLine);
  341.         }
  342.  
  343.     while (*szLine != chEos && (fInQuotedField || *szLine != chSep))
  344.         {
  345.         BOOL fNonSpace;
  346.  
  347.         if (*szLine == chDblQuote)
  348.             {
  349.             if (!fInQuotedField)
  350.                 {
  351.                 if (chSep == chFieldSep)  /* in XL tab file only */
  352.                     {
  353.                     DebugMsgBox(szLineStart, "Badly formed field: Quote in "
  354.                                 "unquoted field");
  355.                     return (szNull);
  356.                     }
  357.                 }
  358.             else
  359.                 {
  360.                 szLine = SzNextChar(szLine);
  361.                 if (*szLine == chSep || *szLine == chEos)
  362.                     {
  363.                     fInQuotedField = fFalse;
  364.                     break;
  365.                     }
  366.                 /* Consecutive double quotes are treated as one quote. */
  367.                 if (*szLine != chDblQuote)
  368.                     {
  369.                     /* Strip off trailing spaces
  370.                     */
  371.                     while (FWhiteSpaceCh(*szLine) && *szLine != chSep)
  372.                         szLine = SzNextChar(szLine);
  373.                     if (*szLine == chSep || *szLine == chEos)
  374.                         {
  375.                         fInQuotedField = fFalse;
  376.                         break;
  377.                         }
  378.                     DebugMsgBox(szLineStart, "Badly formed field: "
  379.                                 "Non-doubled quote in quoted field");
  380.                     return (szNull);
  381.                     }
  382.                 }
  383.             }
  384.         if (cbFieldMaxCur == 0)
  385.             {
  386. #ifdef DEBUG
  387.             CHAR rgch[cchSzMax];
  388.             
  389.             wsprintf(rgch, "Error: Field is too long (>= %d)", cbFieldMax);
  390.             DebugMsgBox(szLineStart, rgch);
  391. #endif
  392.             *szField = chEos;
  393.             return (szNull);
  394.             }
  395.         fNonSpace = (*szLine != chSpace);
  396.         CopyCharToBuf(&szLine, &szField, &cbFieldMaxCur);
  397.         if (fNonSpace)
  398.             szFieldEnd = szField;
  399.         }
  400.  
  401.     if (!fQuotedField)
  402.         szField = szFieldEnd;  /* Strip off trailing spaces */
  403.     *szField = chEos;
  404.  
  405.     if (fInQuotedField)
  406.         {
  407.         DebugMsgBox(szLineStart, "Badly formed field: Unmatched quote");
  408.         return (szNull);
  409.         }
  410.     Assert(*szLine == chEos || *szLine == chSep);
  411.     if (*szLine == chSep)
  412.         szLine = SzNextChar(szLine);
  413.  
  414.     return (szLine);
  415. }
  416.  
  417.  
  418. /*
  419. **    Purpose:
  420. **        Copies a character from one buffer to another and advancing pointers.
  421. **    Arguments:
  422. **        pszCur: Pointer to string to copy character from.
  423. **        pszBuf: Pointer to string to copy character to.
  424. **        pcbBuf: Pointer to useable size of pszBuf.
  425. **    Returns:
  426. **        none.
  427. **    Notes:
  428. **
  429. ****************************************************************************/
  430. VOID PUBLIC CopyCharToBuf ( PSZ pszCur, PSZ pszBuf, PCB pcbBuf )
  431. {
  432.     SZ szEnd = SzNextChar(*pszCur);
  433.  
  434.     if ((CB)(szEnd - *pszCur) <= *pcbBuf)
  435.         {
  436.         while (*pszCur < szEnd)
  437.             {
  438.             *(*pszBuf)++ = *(*pszCur)++;
  439.             (*pcbBuf)--;
  440.             }
  441.         }
  442.     else
  443.         {
  444.         *pszCur = szEnd;
  445.         *pcbBuf = 0;
  446.         }
  447. }
  448.  
  449.  
  450. /*
  451. ************************************************************************/
  452. PLOR PUBLIC PlorFromSz ( OR orCur, SZ sz )
  453. {
  454.     PLOR plor = plorNull;
  455.     SZ   szCur;
  456.     UINT cor;
  457.  
  458.     Assert(sz != szNull);
  459.  
  460. LWalkStringReadingLOR:
  461.     szCur = sz;
  462.     cor = 0;
  463.     while (*szCur != chEos)
  464.         {
  465.         SZ szSep;
  466.  
  467.         while (FWhiteSpaceCh(*szCur))
  468.             szCur = SzNextChar(szCur);
  469.         if (*szCur == chEos)
  470.             break;
  471.         szSep = szCur;
  472.         while (*szSep != chEos
  473.             && !FWhiteSpaceCh(*szSep)
  474.             && *szSep != chLorSep)
  475.             {
  476.             if (!isdigit(*szSep))
  477.                 {
  478.                 ParseError(orCur, STR_OBJID_ERR);
  479.                 FFreePlor(&plor);
  480.                 return (plorNull);
  481.                 }
  482.             szSep = SzNextChar(szSep);
  483.             }
  484.  
  485.         if (plor != plorNull)
  486.             {
  487.             CHAR chSav;
  488.  
  489.             Assert(plor->rgor != rgorNull);
  490.             chSav = *szSep;
  491.             *szSep = chEos;
  492.             plor->rgor[cor] = atoi(szCur);
  493.             *szSep = chSav;
  494.             }
  495.  
  496.         cor++;
  497.         szCur = szSep;
  498.         if (*szCur != chEos)
  499.             szCur = SzNextChar(szCur);
  500.         }
  501.  
  502.     if (plor == plorNull
  503.         && cor > 0
  504.         && (plor = PlorAlloc(cor)) != plorNull)
  505.         {
  506.         Assert(plor->rgor != rgorNull);
  507.         Assert(plor->cor == cor);
  508.         goto LWalkStringReadingLOR;
  509.         }
  510.  
  511.     return (plor);
  512. }
  513.  
  514.  
  515. /*
  516. ************************************************************************/
  517. BOOL PUBLIC FFreePlor ( PPLOR pplor )
  518. {
  519.     PLOR plor = *pplor;
  520.  
  521.     if (plor != plorNull)
  522.         {
  523.         Assert(plor->cor > 0);
  524.         Assert(plor->rgor != rgorNull);
  525.  
  526.         FFree((PB)(plor->rgor), (CB)(plor->cor * sizeof(OR)));
  527.         FFree((PB)plor, (CB)sizeof(LOR));
  528.         *pplor = plorNull;
  529.         }
  530.  
  531.     return (fTrue);
  532. }
  533.  
  534.  
  535. /*
  536. ************************************************************************/
  537. PLOR PUBLIC PlorAlloc ( UINT cor )
  538. {
  539.     PLOR plor;
  540.  
  541.     Assert(cor > 0);
  542.  
  543.     while ((plor = (PLOR)PbAlloc((CB)sizeof(LOR))) == plorNull)
  544.         {
  545.         if (!FHandleOOM())
  546.             return (plorNull);
  547.         }
  548.  
  549.     plor->cor = cor;
  550.     while ((plor->rgor = (RGOR)PbAlloc((CB)(cor * sizeof(OR)))) == rgorNull)
  551.         {
  552.         if (!FHandleOOM())
  553.             {
  554.             FFree((PB)plor, (CB)sizeof(LOR));
  555.             return (plorNull);
  556.             }
  557.         }
  558.  
  559.     return (plor);
  560. }
  561.  
  562.  
  563.  
  564.